﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using LinqKit;

namespace Loef
{
	[DataContract]
	public class PagedData<T>
	{
		[DataMember] public int PageSize { get; set; }
		[DataMember] public int PageIndex { get; set; }
		[DataMember] public int TotalPages { get; set; }
		[DataMember] public int TotalRecords { get; set; }
		[DataMember] public IEnumerable<T> Data;

		public PagedData(IEnumerable<T> data, int pageSize, int pageIndex, int totalPages, int totalRecords)
		{
			Data = data;
			PageSize = pageSize;
			PageIndex = pageIndex;
			TotalPages = totalPages;
			TotalRecords = totalRecords;
		}


		public PagedData(IQueryable<T> query, int pageSize, int pageIndex)
		{
			PageSize = pageSize;
			PageIndex = pageIndex;

			TotalRecords = query.Count();
			TotalPages = (int) Math.Ceiling((double) TotalRecords / PageSize);
			Data = query.Skip(PageIndex * PageSize).Take(PageSize).ToArray();
		}


		public static PagedData<TData> FromQuery<TData, TSource>(IQueryable<TSource> sourceQuery, int pageSize, int pageIndex, Func<TSource, TData> row_selector)
		{
			int totalRecords = sourceQuery.Count();
			int totalPages = (int) Math.Ceiling((double) totalRecords / pageSize);

			TSource[] sourcePage = sourceQuery.Skip(pageIndex * pageSize).Take(pageSize).ToArray();
			// We call ToArray() at the end to force any deferred querying to happen
			IEnumerable<TData> dataPage = sourcePage.Select(sourceRow => row_selector(sourceRow)).ToArray();

			return new PagedData<TData>(dataPage, pageSize, pageIndex, totalPages, totalRecords);
		}

		// With serialization, it's a good idea to have a parameterless constructor
		public PagedData()
		{ }

	}
}
